package org.hoyi.dishop;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.hoyi.DB.comment.DbAttrANNO;
import org.hoyi.DB.conf.HOYIConf;
import org.hoyi.DB.ctrl.Console;
import org.hoyi.DB.ents.Entity;
import org.hoyi.WebRender.HoyiJSConfig;
import org.hoyi.microservice.HoyiCloudApplication;
import org.hoyi.util.CutStrInfo;
import org.hoyi.util.DomainUtil;
import org.hoyi.util.HTMLUtils;
import org.hoyi.util.HttpRequestDeviceUtils;
import org.hoyi.util.MD5Util;
import org.hoyi.util.MethodCutInfo;
import org.hoyi.util.StreamUtils;
import org.hoyi.wb.comment.PostParam;
import org.hoyi.wb.comment.RequestMode;
import org.hoyi.wb.comment.RequestType;
import org.hoyi.web.ctrls.IHoyiCtrl;
import org.hoyi.web.ctrls.Module;
import org.hoyi.web.ctrls.Repeater;
import org.hoyi.web.events.IExcuteKeyListener;
import org.hoyi.loader.*;

import net.sf.json.JSONObject;


/**
 * Author:ellen Email:ellen@kuaifish.com CreateDate:2015-05-20
 * ModifyDate:2015-06-20 hoyi entities @ hoyi.org 浣跨敤璇峰湪椤圭洰鍏充簬鍐呮爣娉╤oyi鐗堟潈锛�
 * hoyi鐗堟潈褰抙oyi.org鎵�鏈�
 */
public class Hoyipage  extends IHoyiCtrl {
	
	/**
	 * 椤甸潰HTML鐨勭紦瀛�.
	 */
	protected static Map<String, String> htmlcache = new HashMap<>();
	
	public Hoyipage pageroot = this;
	public String htmlpath;
	protected Boolean ContainFile = Boolean.valueOf(false);
	
	/**
	 * 是否ModPage,模块化的Page，不支持读取跟输出
	 */
	public boolean isModPage = false;
	/**
	 * 鏄惁鎵撳紑椤甸潰缂撳瓨.
	 * 鍏抽棴鍚庝細闅忔椂鑾峰彇.
	 */
	public static boolean OpenCacheHTML = true;
	
	/**
	 * 外部已经加载了HTML
	 */
	public boolean OuterHTMLLoaded = false;
	
	public Hoyipage parent;
	
	public Hoyipage(){}
	
	
	public Hoyipage(String id, Hoyipage _parent){
		this.parent = _parent;
		this.setId(id);
		// 鏄惁涓虹敤鎴锋帶浠躲��
		this.CTRL_ATTR = true;
		_parent.PageChild.put(id, this);
	}
	/**
	 * 鏄惁鍖呭惈HOYIJS锛屽鏋滃寘鍚殑璇濓紝绯荤粺浼氳嚜鍔ㄥ皢HOYIPOSJS杈撳嚭鍒伴〉闈笂锛岃�屼笉闇�瑕佸紩鐢紝
	 * 褰撳墠閰嶇疆榛樿鏄叧闂殑锛岄渶瑕佷娇鐢ㄧ殑鏃跺�欏彲浠ユ墦寮�
	 * 娉ㄦ剰锛欻OYI POST JS渚濊禆JQUERY锛屽鏋滄兂瑕佷娇鐢ㄧ洿鎺ユ彁浜ゆ柟娉曪紝璇峰紩鍏QUERY銆�
	 */
	private boolean ContainHoyiJS = false;
	
	/**
	 * 鏄惁鍖呭惈JQUERY锛屽洜涓篐OYI POST渚濊禆浜嶫QUERY锛屾墍浠ュ鏋滃紑鍚簡褰撳墠鍔熻兘
	 * 鍒欓〉闈㈣嚜鍔ㄥ紩鍏ュ叕缃戠殑JQUERY鍦板潃锛屼篃鍙互鑷繁璁剧疆JQUERY鍦板潃.
	 */
	private boolean ContainJQuery = false;
	/**
	 * JQUERY鐗堟湰锛岃窡ContainJQUERY閰嶇疆浣跨敤銆�
	 */
	private String JqueryVersion = "";
	/**
	 * JQUERYURL,濡傛灉璁剧疆浜嗗綋鍓嶅�硷紝鍒機ontainJQUERY鍜孞QUERYVERSION澶辨晥.
	 */
	private String JqueryURL = "";
	
	/**
	 * 鍒ゆ柇鎵嬫満鎻愪氦鐨勮姹傘��
	 * @return value
	 */
	public boolean isMobileRequest(){
		return HttpRequestDeviceUtils.isMobileDevice(getRequest());
	}
	/**
	 * 鑾峰彇MD5瀛楃涓�.
	 * @param encstr
	 * @return
	 */
	public String GetMD5_STR(String encstr) {
		return MD5Util.getMD5String(encstr);
	}
	/**
	 * hoyip.html鏂囦欢璇诲閮╤tml
	 * @param url
	 * @return value
	 */
	public String WRITEHTML(String url){
//		return HTMLUtils.instance().WRITEHTML(getRequest(), url, this);
		return HTMLUtils.instance().WRITEHTMLResourceAsStream(getRequest(), url);
	}
	
	/**
	 * 鏇挎崲鐗规畩绗﹀彿
	 * @param data
	 * @return value
	 */
	public String EJS(String data){
		if(data != null && data.length() > 0){
//			data = data.replace("&", "\\&").replace("'", "\\'").replace(" ", "\\ ").replace("<", "\\<").replace(">", "\\>").replace("\"", "\\\"");
			data = data.replace("&", "&amp;").replace("'", "\\'").replace(" ", "&nbsp;").replace("<", "&lt;").replace(">", "&gt;").replace("\"", "&quot;").replace("%", "&#37;");
			return data;
		}
		return "";
	}
	
	/**
	 * 鐢ㄦ埛鎺т欢.
	 */
	public Map<String, Hoyipage> PageChild = new HashMap<>();
	
	/**
	 * 鑾峰彇绯荤粺鍚姩鏃堕棿.
	 */
	@RequestMode(MODE= {RequestType.GET, RequestType.POST})
	public void Get_Sys_StartingTime() {
		this.WriteUTF8JSONDATAMSG(1, "", HoyiCloudApplication.cloud_staringtime);
	}
	
	/**
	 * 鏄惁鎺т欢灞炴�э紝鑻ヤ负鎺т欢灞炴�э紝鍒欎笉浣跨敤response.write杈撳嚭.
	 */
	public boolean CTRL_ATTR = false;

	/**
	 * 加载并渲染的HTML.
	 */
//	protected String HtmlContent;
	
	/**
	 * 输出的HTML
	 */
	protected String retObjs;

	protected boolean IsPostBack() {
		if (getParams("ispostback") == null) {
			return true;
		}
		return Boolean.parseBoolean(getParams("ispostback"));
	}
	
	public String GetValueById(String idString){
		return idString;
	}
	
	HashMap<String, HashMap<String, String>>  clickParas = new HashMap<>();
	
	public void PutClickPara(String eventid, String paramname, String paraelmid){
		if(clickParas.containsKey(eventid)){
			HashMap<String, String> pems = clickParas.get(eventid);
			pems.put(paramname, paraelmid);
			clickParas.put(eventid, pems);
		}else{
			HashMap<String, String> pems = new HashMap<>();
			pems.put(paramname, paraelmid);
			clickParas.put(eventid, pems);
		}
		
	}
	
	/**
	 * 鑾峰彇瀹氫箟鍦ㄦ柟娉曞ご鐨勮姹傚弬鏁板苟鐢熸垚JS.
	 * @return value
	 */
	public String GetPostPInMethod(){
//		return "var HOYIPOST_EVENTPAMS = [{ 'eventid': 'JJ', 'params': [ 'time','aa'] }];";
		
		String HOYIPOST_EVENTPAMS = "";
		
		Method[] methods = this.getClass().getDeclaredMethods();
		String[] ppms = null;
		PostParam[] _pParam = null;
		Class<?> cc = null;
		for (Method method : methods) {
			if(method.isAnnotationPresent(PostParam.class)){
				// 璇存槑瀹氫箟浜嗗弬鏁拌鏄�.
				HOYIPOST_EVENTPAMS = HOYIPOST_EVENTPAMS + "{'eventid': '" + method.getName() + "','params': [";

				_pParam = (PostParam[]) method.getAnnotationsByType(PostParam.class);
				for (PostParam postParam : _pParam) {
					ppms = postParam.PARMS();
					for (String ss : ppms) {
						HOYIPOST_EVENTPAMS = HOYIPOST_EVENTPAMS + "'" + ss +"',";
					}
					cc = postParam.ENTITY();
					try{
						
						if (cc.newInstance() instanceof Entity) {
							Field[] fields = cc.getDeclaredFields();
							for (Field field : fields) {
								// 濡傛灉涓嶆槸 DbAttrAnno锛屽垯娣诲姞鍒板弬鏁�.
								if (!field.isAnnotationPresent(DbAttrANNO.class)) {
									HOYIPOST_EVENTPAMS = HOYIPOST_EVENTPAMS + "'" + field.getName() +"',";	
								}
							}
						}	
					}catch(Exception ex){
						
					}
				}
				if(HOYIPOST_EVENTPAMS.endsWith(",")){
					HOYIPOST_EVENTPAMS = HOYIPOST_EVENTPAMS.substring(0, HOYIPOST_EVENTPAMS.length() - 1);
				}

				HOYIPOST_EVENTPAMS =  HOYIPOST_EVENTPAMS + "]},";
			}

		}
		if(HOYIPOST_EVENTPAMS.endsWith(",")){
			HOYIPOST_EVENTPAMS = HOYIPOST_EVENTPAMS.substring(0, HOYIPOST_EVENTPAMS.length() - 1);
		}
		
		
		
		// 鍔犲瘑JSON.
		HOYIPOST_EVENTPAMS =  HOYIPOST_EVENTPAMS ;
		
		HOYIPOST_EVENTPAMS = "<script type=\"text/javascript\"> "
				+ "var HOYIPOST_EVENTPAMS = ["  +  HOYIPOST_EVENTPAMS +  "]; "
				+ "var HoyipRd= '" + HOYIConf.HRSA_Modules+";"+HOYIConf.HRSA_Exponent + "';"  // 鍏挜妯¤窡鎸囨暟.
				
				+ GetKeepAlivaListening() 
				+ "</script>";
		
		return HOYIPOST_EVENTPAMS;
	}
	
	public String GetKeepAlivaListening() {
		return "";
	}
	
	/**
	 * 鑾峰彇鍦≒reLoad瀹氫箟鐨勬柟娉�.
	 * @return value
	 */
	public String GetInitPara() {
		
//		return "var HOYICLICK_EVENTID = [			"+
//               "{										"+
//               "     'eventid': 'JSTT',						"+
//               "     'params': { 'times': '#txtext' }				"+
//               " }			"+
//               "];";
		
		String ccpp = "<script type=\"text/javascript\">"
				+ "var HOYICLICK_EVENTID = [";
		
		
		Iterator iter = clickParas.entrySet().iterator();
		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			
			HashMap<String, String> values = (HashMap<String, String>) entry.getValue();
			ccpp = ccpp + "{     'eventid': '" + entry.getKey()  + "','params':{";

			Iterator valueiter = values.entrySet().iterator();
			while (valueiter.hasNext()) {
				Map.Entry valueentry = (Map.Entry) valueiter.next();
				ccpp = ccpp + "     '" + valueentry.getKey() +"': '" + valueentry.getValue() +"' ,";
			}
			if(ccpp.endsWith(",")){
				ccpp = ccpp.substring(0, ccpp.length() - 1);
			}
			ccpp = ccpp + "}  }";
		}
		ccpp = ccpp + "];";
		ccpp = ccpp + "</script>";
		
//		System.out.println("CCPP:" + ccpp);
		return ccpp;
	}
	
	/**
	 * 鐩戝惉椤甸潰鏄惁鏄渶鏂扮殑銆�
	 * @return
	 */
	public String MotionPage_Newest() {
		return "<script type=\"text/javascript\">\n" + 
				"		var native_getx = {\n" + 
				"		    get: function(url,fn){\n" + 
				"		        // XMLHttpRequest瀵硅薄鐢ㄤ簬鍦ㄥ悗鍙颁笌鏈嶅姟鍣ㄤ氦鎹㈡暟鎹甛n" + 
				"		        var xhr=new XMLHttpRequest();\n" + 
				"		        xhr.open('GET',url,false);\n" + 
				"		        xhr.onreadystatechange=function(){\n" + 
				"		            // readyState == 4璇存槑璇锋眰宸插畬鎴怽n" + 
				"		            if(xhr.readyState==4){\n" + 
				"		                if(xhr.status==200 || xhr.status==304){\n" + 
				"		                	var responseText = xhr.responseText;\n" + 
				"		                    console.log(responseText);\n" + 
				"		                    var rdata = JSON.parse(responseText);\n" + 
				"		                    fn(rdata, xhr.status);\n" + 
				"		                }\n" + 
				"		            }\n" + 
				"		        }\n" + 
				"		        xhr.send();\n" + 
				"		    },\n" + 
				"		}\n" + 
				"\n" + 
				"		var hoyi_sys_running = -2;\n" + 
				"\n" + 
				"		function Check_SYS_REFRESH(){\n" + 
				"			var url = \"?behavior=Get_Sys_StartingTime\";\n" + 
				"			native_getx.get(url, function(rdata,ret_status){\n" + 
				"				var data = rdata.data;\n" + 
				"				var status = rdata.status;\n" + 
				"				if(status == 1){\n" + 
				"					var canload = false;\n" + 
				"					if(hoyi_sys_running != -2 && hoyi_sys_running != data){\n" + 
				"						canload = true;\n" + 
				"					}\n" + 
				"					if(canload){\n" + 
				"						window.location.reload();\n" + 
				"					}\n" + 
				"\n" + 
				"					hoyi_sys_running = data;\n" + 
				"				}\n" + 
				"			})\n" + 
				"		}\n" + 
				"		$(function(){\n" + 
				"			setInterval(Check_SYS_REFRESH, " +	HoyiCloudApplication.Motion_Page_Newest_millons + ");\n" + 
				"		})\n" + 
				"	</script>";
	}
	
	public String GetRootURL()
	{
		return DomainUtil.GetRootURL(parent.getClass());
	}
	
	@Override
	public boolean ExeBehavior() {
		// TODO Auto-generated method stub
		boolean superex = super.ExeBehavior();
		if (superex) {
			return superex;
		}

		boolean tempex=false;

		Hoyipage tmppage;
		for (String _id : this.PageChild.keySet()) {
			tmppage = this.PageChild.get(_id);
			tmppage.CTRL_ATTR = true;
			tmppage.setRequest(this.getRequest());
			tmppage.setResponse(this.getResponse());
			tmppage.currentReqType = this.currentReqType;

			tmppage.exinstance = tmppage;
			
			tmppage.InitContentByTemplates(HtmlContent);
			tempex = tmppage.ExeBehavior();
			 
			//if (tempex) {
				return true;
			//}
		}

		return false;
	}

	public boolean _containmds = false; 
	
	public String ExSimpleMDS(String _template){
		Method[] methods = new Method[]{};
		
		
		while ((_template.contains("<%#")) && (_template.contains("%>"))) {
			CutStrInfo cuts = new CutStrInfo("<%#", "%>", _template);
			Console.Info("Contain Method:" + cuts.EXPREDContent);

			boolean containmethod = cuts.Calc(false);
			String tmp = "<%#" + cuts.EXPREDContent + "%>";

			if (containmethod) {
				MethodCutInfo minfo = new MethodCutInfo();
				minfo.Calc(cuts.EXPREDContent);
				// 濡傛灉鏄潤鎬佸睘鎬ф垨鏂规硶锛屽垯鍔犲叆闈欐�佸睘鎬ф垨鏂规硶鎵ц
//				if(minfo.methodName.startsWith(cuts.EXPREDContent))
					

				Console.Info("MethodName:" + minfo.methodName);
				for (int i = 0; i < minfo.params.length; i++) {
					Console.Info("Params:" + minfo.params[i]);
				}
				for (int i = 0; i <4; i ++){
					switch (i) {
						case 0:
							methods = Hoyipage.this.exinstance.getClass().getDeclaredMethods();
							break;
						case 1:
							methods = Hoyipage.this.exinstance.getClass().getSuperclass().getDeclaredMethods();
							break;
						case 2:
							methods = Hoyipage.this.exinstance.getClass().getSuperclass().getSuperclass().getDeclaredMethods();
							break;
						case 3:
							methods = Hoyipage.this.exinstance.getClass().getSuperclass().getSuperclass().getSuperclass().getDeclaredMethods();
							break;
					}
					for (Method mds : methods) {
						if (mds.getName().equals(minfo.methodName)) {
							// System.out.println("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM:"
							// + mds.getName());
							try {
								Object mstrs;
								// Object mstrs;
								if (mds.getParameterCount() > 0)
									mstrs = mds.invoke(Hoyipage.this.exinstance, minfo.params);
								else {
									mstrs = mds.invoke(Hoyipage.this.exinstance, new Object[0]);
								}
								_containmds = true;
								if (mstrs != null){
									//Console.Info("mstrs:" + mstrs);
								}
								else {
									Console.Info("mstrs is null");
								}
								if (_template.contains(tmp)) {
									_template = _template.replace(tmp, mstrs.toString());
								} else {
									_template = _template.replace(tmp, "<p>X_Can Not Find METHOD: " + cuts.EXPREDContent + "</p>");
									Console.Info("No Contained.");
									_containmds = false;
								}
							} catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException e){
								Console.Error("any error here:" + e.getMessage());
							}
						}
					}
				}
				
				_template = _template.replace(tmp, "<p>Y_Can Not Find METHOD: " + cuts.EXPREDContent + "</p>");
			} else {
				tmp = "<%#" + cuts.EXPREDContent + "%>";
				Console.Error("<p>Can Not Find METHOD: " + cuts.EXPREDContent + "</p>");
				_template = _template.replace(tmp, "<p>Can Not Find METHOD: " + cuts.EXPREDContent + "</p>");
				_containmds = false;
			}
		}
		return _template;
	}

	public void OnPreInit() throws IOException {
//		Console.Info("OnPreInit");
		this.exinstance = this;

		IExcuteKeyListener ExListener = new IExcuteKeyListener() {
			public String Execute(String _template) {
				return ExSimpleMDS(_template);
			}
		};
		this.pageroot.ExecuteListener = ExListener;

		OnExBehavior();
	}

	public void OnExBehavior() throws IOException {
		ExeBehavior();
		if (this.Behaviored) {
			return;
		}
		OnInit();
	}

	public void OnInit() throws IOException {
		OnPageLoad();
	}

	public void LoadHoyiHTML() throws IOException {
		//Console.Info("OnPageLoad()");
		
		this.htmlpath = getClass().toString();
		this.htmlpath = this.htmlpath.substring(6);
		this.htmlpath = this.htmlpath.replace(".", "/");
		
		if(themehtmls != null && themehtmls.length() > 0){
			int lastindex = this.htmlpath.lastIndexOf("/");
			if(lastindex > 0){
				htmlpath = htmlpath.substring(0, lastindex + 1);	
				htmlpath += themehtmls;	
			}else{
				htmlpath = themehtmls;	
			}
		}
		this.htmlpath += htmlostype;
		// 这里如果是开启了本地的服务，就要从本地来拿HTML，而不是从包里面拿.
		if(this.isModPage) {
			this.htmlpath += ".hoyimp.html";
		}else {
			this.htmlpath += ".hoyip.html";
		}
		Console.Info("htmlPath:" + htmlpath);	
		// Windows 璇风敤杩欎釜.
		// this.htmlpath = (getRequest().getRealPath("/") + "\\WEB-INF\\classes" + this.htmlpath);
		// 閫傚簲Linux淇敼
		// this.htmlpath = (getRequest().getRealPath("/") +File.separator +"WEB-INF" +File.separator +"classes" + this.htmlpath);

		// 椤甸潰缂撳瓨锛岃繖閲屽彲浠ュ姞涓紑鍏筹紝鍒ゆ柇鏄惁闇�瑕佸姞椤甸潰缂撳瓨銆�
		if(OpenCacheHTML && htmlcache.keySet().contains(this.htmlpath)) {
			HtmlContent = htmlcache.get(this.htmlpath);
		}else {
			String contents;
			
			try {
				byte[] bts;
				if(HoyiCloudApplication.OpenLocalWebRoot) {
					String path = HoyiCloudApplication.WebRootPath + htmlpath;
					Console.Info("read local .htmlPath:" + path);	
					bts = StreamUtils.Create().ReadLocalFileResource(path);
				}else {
					bts = StreamUtils.Create().ReaderResource(htmlpath);
				}
				contents = new String(bts, "UTF-8");
				ContainFile = true;
			} catch (Exception e) {
//				if(JarLoader.resMap.containsKey(htmlpath)) {
//					byte[] bts = JarLoader.resMap.get(htmlpath);
//					contents = new String(bts, "UTF-8");
//					ContainFile = true;
//				}else {

					ContainFile = false;
					WriteUTF8Text("Can not find hoyi page html file." + this.htmlpath);
					Console.Error(e);
					return;
//				}
			}
			
			HtmlContent = contents.toString();
			if(HoyiCloudApplication.AutoRefreshPage) {
				if (!getParams("hoyiautofresh").equals("disabled")) {
					HtmlContent = HtmlContent.replaceFirst(
							"<head>", 
							"<head><meta http-equiv=\"refresh\" content=\"" +HoyiCloudApplication.AutoRefreshSeconds + "\">");
				}
			}
			htmlcache.put(this.htmlpath, HtmlContent);
		}

		getResponse().setContentType("text/html");
		getResponse().setCharacterEncoding("utf-8");

		//Console.Info("hoyipage url:" + this.htmlpath);
	}

	public void OnPageLoad() {
		if(!OuterHTMLLoaded) {
			try {
				LoadHoyiHTML();
				OnPageLoaded();
			} catch (Exception e) {
				Console.Error(e);
			}
		}else {

			getResponse().setContentType("text/html");
			getResponse().setCharacterEncoding("utf-8");
			
			OnPageLoaded();
		}
	}

	public IHoyiCtrl LoadCtrl(String ctrlid) {
		return new Repeater(ctrlid);
	}

	public void OnPageLoaded() {
		//Console.Info("OnPageLoaded()");
		OnAuthenticate();
	}

	public void OnAuthenticate() {
		//Console.Info("OnAuthenticate()");
		OnValidate();
	}

	public void OnValidate() {
		//Console.Info("OnValidate()");
		OnRender();
	}

	public void OnRender() {
		//Console.Info("OnRender()");
		// 鎵ц椤甸潰鏂规硶
		//HtmlContent = this.pageroot.TransEXCUTEMethod(HtmlContent);
		
		// Module瀵规ā鐗堣繘琛屾覆鏌�,杩欓噷鍙互鎶婅兘娓叉煋鐨勭被寮勪釜鏁扮粍锛岄渶瑕佽嚜宸辨覆鏌撶殑璇濓紝灏卞垵濮嬪寲涓�涓潤鎬佺被锛岀劧鍚庡惊鐜覆鏌�.
		HtmlContent = Module.RenderModule(this, HtmlContent);
		
		// Console.Error(this.pageroot.childrends.size());
		Repeater tmprep;
//		UserControl tmpuscontrol ;
		String tmpContent ;
		
		for (String id : this.pageroot.childrends.keySet()) {
			IHoyiCtrl ctrl = (IHoyiCtrl) this.pageroot.childrends.get(id);
			if ((ctrl instanceof Repeater)) {
				try {
					tmprep = (Repeater) this.pageroot.childrends.get(id);
					tmprep.InitContentByTemplates(HtmlContent);
					tmpContent = ctrl.Render();
					if (!StringUtils.isEmpty(tmprep.HtmlContent)) {
						HtmlContent = HtmlContent.replace(tmprep.HtmlContent, tmprep.rendedHTMLContent);
					}
				} catch (Exception e) {
					Console.Error("Repeater.Render Error, id:" + ctrl.getId());
				}
			}
		}
		if(HtmlContent == null)
			HtmlContent = "";
		// 鎵ц椤甸潰鏂规硶
		HtmlContent = this.pageroot.TransEXCUTEMethod(HtmlContent);
		OnWriteHTML();
	}
	/**
	 * 娓叉煋瀛愭ā鐗�.
	 * @param childctrl  瀛愭帶浠�
	 * @param _datacount 鏁版嵁婧愰暱搴�.
	 * @return
	 */
	public String RenderChild(IHoyiCtrl childctrl, int _datacount) {
		
		IHoyiCtrl ctrl2 = GetById(childctrl.getId());
		ctrl2.ExecuteListener = this.pageroot.ExecuteListener;
		ctrl2.setPageIndex(getpgindex());
		ctrl2.setPageCount(childctrl.getPageCount());
		ctrl2.CalcPageCount(_datacount, childctrl.getPageSize());
		if (ctrl2 != null) {
			return ctrl2.getRendedHTMLContent();
		}
		return "";
	}
	/**
	 * 妯＄増鏄惁宸茬粡娓叉煋浜哅odule,鍦ㄩ噸澶嶈皟鐢ㄦ覆鏌撶殑鏃跺�欑敓鏁�.
	 */
	public boolean modluerended = false;

	public IHoyiCtrl GetById(String ctrlid) {
		IHoyiCtrl ctrl = null;

		if (StringUtils.isEmpty(HtmlContent)) {
			try {
				LoadHoyiHTML();
			} catch (IOException e) {
				Console.Error(e);
				return null;
			}
		}
		
		if(!modluerended) {
			// 鏈塎odule鐨勬椂鍊欙紝闇�瑕佸厛灏哅oduel Render鍑烘潵锛屽啀鍋氭覆鏌�.銆�
			HtmlContent = Module.RenderModule(this, HtmlContent);
			modluerended = true;
		}

		for (String id : this.pageroot.childrends.keySet()) {
			if (id.equals(ctrlid)) {
				ctrl = (IHoyiCtrl) this.pageroot.childrends.get(id);
				ctrl.ExecuteListener = this.pageroot.ExecuteListener;
				if ((ctrl != null) && ((ctrl instanceof Repeater))) {
					ctrl.InitContentByTemplates(HtmlContent);

					ctrl.Render();
				}
			}
		}

		return ctrl;
	}
	/**
	 * 灏哋bject杞崲涓� 璇锋眰鍙傛暟.PS:a=x&b=x
	 * @param obt
	 * @return
	 */
	public String JoinParaJSON(JSONObject obt) {
		String ret = "";
		String key = "";

		Iterator<String> it = obt.keys();
		while(it.hasNext()){
			// 鑾峰緱key
			key = it.next(); 
			ret = ret + "&" + key + "=" + obt.getString(key);
		}
		if(ret.startsWith("&")) {
			ret = ret.substring(1, ret.length());
		}
		return ret;
	}
	/**
	 * 灏哋bject杞崲涓� 璇锋眰鍙傛暟.PS:a=x&b=x
	 * @param obt
	 * @return
	 */
	public String JoinPara(Map<String, String> obt) {
		String ret = "";
		for (String key : obt.keySet()) {
			ret = ret + "&" + key + "=" + obt.get(key);
		}
		if(ret.startsWith("&")) {
			ret = ret.substring(1, ret.length());
		}
		return ret;
	}
	/**
	 * 鏍规嵁鍙傛暟杩炴帴鎴愯姹傜殑鍙傛暟.. PS:a=x&b=x
	 * @param paras
	 * @return
	 */
	public String JoinPara(String... paras) {
		String ret = "";
		String key = "";
		for (int i = 0; i < paras.length; i++) {
			if(i%2 == 0) {
				key = paras[i];
				ret = ret + "&" + key + "=" + paras[i + 1];
			}
		}
		if(ret.startsWith("&")) {
			ret = ret.substring(1, ret.length());
		}
		return ret;
	}
	/**
	 * Jquery Libraries.
	 * @return value
	 */
	public String JqueryLib() {
		String hoyipostjs = "";
		if(getJqueryURL().trim().length() > 0) { // 濡傛灉鏈湴璁剧疆浜咼query璺緞锛屽垯JqueryVersion绛夊け鏁�.
			hoyipostjs += "		<script typet=\"text/javascript\" src=\"" + getJqueryURL() + "\"></script>\n";
		}else {
			if(this.getJqueryVersion().trim().length() > 0) {
				String versionurl = "";
				versionurl = HoyiJSConfig.getInstance().GetJqueryByVarsion(this.getJqueryVersion());
				hoyipostjs += "		<script typet=\"text/javascript\" src=\"" + versionurl + "\"></script>\n";
			}else {
				hoyipostjs += "		<script typet=\"text/javascript\" src=\"" + HoyiJSConfig.getInstance().defJqueryURL + "\"></script>\n";
			}
		}
		return hoyipostjs;
	}
	
	/**
	 * Jquery ValiLib
	 * @return value
	 */
	public String JqueryValidatorLib() {
		return HoyiJSConfig.getInstance().GetJqueryValiLibs();
	}
	
	/**
	 * jquery,bootstrap,  cdn澶辨晥鐨勮瘽锛屾敼搴曞眰灏監K浜嗐��
	 * @return value
	 */
	public String BootstrapLib(){
		return HoyiJSConfig.getInstance().GetBootStrapLibs();
	}
	/**
	 * hoyi-req.js
	 * hoyi-server-req.v.1.31.s
	 * @return value
	 */
	public String HoyiReqLib() {
		return HoyiJSConfig.getInstance().GetHoyiReqLib();
	}
	
	/**
	 * jquery.js
	 * hoyi-req.js
	 * hoyi-server-req.v.1.31.js
	 * @return value
	 */
	public String HoyReqWJquery() {
		return JqueryLib() + HoyiReqLib();
	}
	
	/**
	 * 榛樿hoyi page 鎻愪氦,
	 * jquery + bootstrap + jqueryvalidator + hoyireq
	 * @return value
	 */
	public String DefHoyiPageLib() {
		return JqueryLib() + BootstrapLib() + JqueryValidatorLib() + HoyiReqLib();
	}
	/**
	 * 閫氱敤HoyiPage 闇�瑕佺殑js,css鏂囦欢寮曠敤銆�
	 * @return value
	 */
	public String HoyiLib() {
		return DefHoyiPageLib();
	}
	
	/**
	 * SB Admin
	 * @return value
	 */
	public String SBAdminLib() {
		return "		<link href=\"https://cdn.bootcss.com/startbootstrap-sb-admin-2/3.3.7+1/css/sb-admin-2.min.css\" rel=\"stylesheet\">\n"
				+"		<script src=\"https://cdn.bootcss.com/startbootstrap-sb-admin-2/3.3.7+1/js/sb-admin-2.min.js\"></script>\n";
	}
	
	/**
	 * 甯query,hoyi,bootstrap, sbadmin
	 * @return value
	 */
	public String HoyiPageSBAdminLib() {
		return DefHoyiPageLib() + SBAdminLib();
	}
	
	/**
	 * 璁剧疆鏄惁闇�瑕佸姞杞絁QUERY鍜孒OYI REQ,HOYI SERVER POST,
	 * 寮�鍚簡涔嬪悗锛屽垯涓嶉渶瑕佸紩鐢↗query鍜孒OYIPOST鏂囦欢浜嗐��
	 * 娉ㄦ剰涓嶈閲嶅寮曠敤銆�
	 * 璁剧疆鐨勬椂鍊欒閲嶅啓OnPreInit()鏂规硶锛屽苟缃簬super.OnPreInit()涔嬪墠.
	 */
	public String GetHoyiPostJS() {
		String hoyipostjs = "";
		
		if(isContainJQuery()) {
			hoyipostjs += JqueryLib();
		}
		if (isContainHoyiJS()) {
			hoyipostjs += HoyiReqLib();
		}
		
		return hoyipostjs;
	}

	private boolean iscontaininitpara = true;

	public void setContainInitPara(boolean containpara){
		iscontaininitpara = containpara;
	}

	public boolean IsContainInitPara(){
		return iscontaininitpara;
	}

	public void OnWriteHTML()
	{
		if (!CTRL_ATTR) {
			// 鍐欏弬鏁版柟娉曞拰鍥烘湁HTML.
			retObjs = "";
			retObjs += HtmlContent;
			if(this.IsContainInitPara()){
				retObjs += GetPostPInMethod() + GetInitPara();
			}
			if(this.isContainHoyiJS()) {
				retObjs +=  GetHoyiPostJS();
				//WriteUTF8HTML(HtmlContent + GetPostPInMethod() + GetInitPara() + GetHoyiPostJS());
			}
//			if(HoyiCloudApplication.Motion_Page_Newest) {
//				retObjs += MotionPage_Newest();
//				retObjs = retObjs.replace("<title>", "<title>[hoyi.motioning]");
//			}
			if(HoyiCloudApplication.Motion_Page_Newest) {
				retObjs = "<script type=\"text/javascript\" src=\"/res/js/hoyi/hoyi-page-motion.js\"></script>"
						+ "<script type=\"text/javascript\" >isconsole_hoyi_page_motion = " + HoyiCloudApplication.Motion_Page_Newest_Console_Log + ";setInterval(Hoyi_Page_Refresh_Motion, " + HoyiCloudApplication.Motion_Page_Newest_millons + ")</script>"
						+ retObjs;
			}
				//WriteUTF8HTML(HtmlContent + GetPostPInMethod() + GetInitPara() );
			if (!isModPage) {
				WriteUTF8HTML(retObjs);	
			}
			// 涓嶄娇鐢≒UTEVENT鏂规硶锛屽叏閮ㄤ娇鐢ㄥご鐨勬柟娉曘��
			//WriteUTF8HTML(HtmlContent + GetPostPInMethod());
			OnEnd();
		}
	}

	public boolean isContainHoyiJS() {
		return ContainHoyiJS;
	}

	public void setContainHoyiJS(boolean containHoyiJS) {
		ContainHoyiJS = containHoyiJS;
	}

	public boolean isContainJQuery() {
		return ContainJQuery;
	}

	public void setContainJQuery(boolean containJQuery) {
		ContainJQuery = containJQuery;
	}

	public String getJqueryVersion() {
		return JqueryVersion;
	}

	public void setJqueryVersion(String jqueryVersion) {
		JqueryVersion = jqueryVersion;
	}

	public String getJqueryURL() {
		return JqueryURL;
	}

	public void setJqueryURL(String jqueryURL) {
		JqueryURL = jqueryURL;
	}

	public void OnEnd() {
		Console.Info("OnEnd()");
	}
}
